#!/usr/bin/env python3
"""
API客户端模块
- 与后台API通信
- 重试机制
- 超时处理
"""

import requests
import time
import logging
from typing import Dict, List
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry


class APIClient:
    """后台API客户端"""

    def __init__(self, config: Dict):
        """
        初始化API客户端

        Args:
            config: backend配置
                - api_url: 基础URL（如 http://localhost:8001）
                - api_prefix: API前缀（如 /api）
                - timeout: 超时时间
                - retry_times: 重试次数
                - retry_interval: 重试间隔
        """
        self.api_url = config['api_url'].rstrip('/')
        self.api_prefix = config.get('api_prefix', '/api').rstrip('/')
        self.timeout = config.get('timeout', 30)
        self.retry_times = config.get('retry_times', 3)
        self.retry_interval = config.get('retry_interval', 5)

        # 创建会话
        self.session = requests.Session()

        # 配置重试策略
        retry_strategy = Retry(
            total=self.retry_times,
            backoff_factor=1,
            status_forcelist=[429, 500, 502, 503, 504],
        )
        adapter = HTTPAdapter(max_retries=retry_strategy)
        self.session.mount("http://", adapter)
        self.session.mount("https://", adapter)

        self.logger = logging.getLogger(__name__)

        # 打印初始化信息（用于调试）
        self.logger.info(f"API客户端初始化 - Base URL: {self.api_url}")
        self.logger.info(f"API客户端初始化 - API Prefix: {self.api_prefix}")
        self.logger.info(f"API客户端配置 - Timeout: {self.timeout}s, Retry: {self.retry_times}次")

    def batch_create_works(
        self, batch_name: str, worker_machine: str, platform: int, works: List[Dict]
    ) -> Dict:
        """
        批量创建作品

        Returns:
            {
                'success': True/False,
                'batchId': 123,
                'created': 50,
                'skipped': 50,
                'needTranscribeList': [...]
            }
        """
        url = f"{self.api_url}{self.api_prefix}/worker/batch-create"

        payload = {
            "batchName": batch_name,
            "workerMachine": worker_machine,
            "platform": platform,
            "works": works,
        }

        try:
            self.logger.info(f"批量上报作品: {len(works)}条")
            self.logger.info(f"请求URL: {url}")
            self.logger.debug(f"请求参数: batchName={batch_name}, workerMachine={worker_machine}, platform={platform}")
            self.logger.debug(f"作品数据量: {len(works)}条")

            response = self.session.post(
                url, json=payload, timeout=self.timeout
            )

            self.logger.info(f"响应状态码: {response.status_code}")
            response.raise_for_status()
            result = response.json()

            self.logger.info(
                f"上报成功: 新建{result.get('created', 0)}条, "
                f"跳过{result.get('skipped', 0)}条, "
                f"需要转录{len(result.get('needTranscribeList', []))}条"
            )

            return result

        except requests.exceptions.RequestException as e:
            self.logger.error(f"批量创建作品失败")
            self.logger.error(f"错误类型: {type(e).__name__}")
            self.logger.error(f"错误详情: {str(e)}")
            self.logger.error(f"请求URL: {url}")
            return {'success': False, 'message': str(e)}

    def submit_transcription(
        self,
        platform: int,
        work_id: str,
        worker_machine: str,
        transcription: Dict,
    ) -> Dict:
        """
        提交转录结果

        Args:
            transcription: {
                'rawText': '...',
                'polishedText': '...',
                'polishStatus': 'success',
                'language': 'zh',
                'processingTime': 45,
                'engine': 'whisper-tiny',
                'polishEngine': 'deepseek-chat'
            }
        """
        url = f"{self.api_url}{self.api_prefix}/worker/submit-transcription"

        payload = {
            "platform": platform,
            "workId": work_id,
            "workerMachine": worker_machine,
            "transcription": transcription,
        }

        try:
            response = self.session.post(
                url, json=payload, timeout=self.timeout
            )
            response.raise_for_status()
            result = response.json()

            if result.get('success'):
                self.logger.info(f"上报转录成功: {work_id}")
            else:
                self.logger.error(f"上报转录失败: {result.get('message')}")

            return result

        except requests.exceptions.RequestException as e:
            self.logger.error(f"上报转录失败: {str(e)}")

            # 重试
            for retry in range(self.retry_times):
                self.logger.info(f"重试 {retry + 1}/{self.retry_times}...")
                time.sleep(self.retry_interval * (retry + 1))

                try:
                    response = self.session.post(
                        url, json=payload, timeout=self.timeout
                    )
                    response.raise_for_status()
                    return response.json()
                except:
                    continue

            return {'success': False, 'message': str(e)}

    def submit_failed(
        self, worker_machine: str, failed_works: List[Dict]
    ) -> Dict:
        """
        提交失败记录

        Args:
            failed_works: [
                {
                    'platform': 0,
                    'workId': 'BV123',
                    'errorMessage': '转录超时',
                    'errorType': 'timeout'
                }
            ]
        """
        url = f"{self.api_url}{self.api_prefix}/worker/submit-failed"

        payload = {
            "workerMachine": worker_machine,
            "failedWorks": failed_works,
        }

        try:
            response = self.session.post(
                url, json=payload, timeout=self.timeout
            )
            response.raise_for_status()
            result = response.json()

            self.logger.info(
                f"上报失败记录: {result.get('recorded', 0)}条"
            )

            return result

        except requests.exceptions.RequestException as e:
            self.logger.error(f"上报失败记录失败: {str(e)}")
            return {'success': False, 'message': str(e)}

    def health_check(self) -> bool:
        """健康检查"""
        health_url = f"{self.api_url}{self.api_prefix}/health"
        try:
            self.logger.info(f"健康检查 - 请求URL: {health_url}")
            # 尝试访问后台健康检查接口
            response = self.session.get(health_url, timeout=10)
            self.logger.info(f"健康检查 - 响应状态码: {response.status_code}")
            if response.status_code == 200:
                result = response.json()
                self.logger.info(f"健康检查 - 响应内容: {result}")
                # 检查是否真的是健康检查响应
                if result.get('status') == 'ok':
                    return True
                else:
                    self.logger.warning(f"健康检查返回异常: {result}")
                    return False
            return False
        except Exception as e:
            self.logger.error(f"健康检查失败 - 错误类型: {type(e).__name__}")
            self.logger.error(f"健康检查失败 - 错误详情: {str(e)}")
            self.logger.error(f"健康检查失败 - 请求URL: {health_url}")
            return False

    def get_need_repolish(self, platform: int, batch_id: int = None, limit: int = 100) -> Dict:
        """
        获取需要补充润色的作品列表

        Args:
            platform: 平台代码
            batch_id: 批次ID（可选）
            limit: 返回数量限制

        Returns:
            {
                'success': True/False,
                'total': 10,
                'works': [
                    {
                        'platform': 0,
                        'workId': 'xxx',
                        'databaseId': 123,
                        'title': '标题',
                        'author': '作者',
                        'rawText': '原始转录文本',
                        'polishStatus': None/2
                    },
                    ...
                ]
            }
        """
        url = f"{self.api_url}{self.api_prefix}/worker/need-repolish"

        params = {
            'platform': platform,
            'limit': limit
        }
        if batch_id:
            params['batchId'] = batch_id

        try:
            self.logger.info(f"获取需要润色的作品列表 - Platform: {platform}")
            response = self.session.get(url, params=params, timeout=self.timeout)
            response.raise_for_status()
            result = response.json()

            if result.get('success'):
                self.logger.info(f"找到 {result.get('total', 0)} 个需要润色的作品")
            return result

        except requests.exceptions.RequestException as e:
            self.logger.error(f"获取需要润色列表失败: {str(e)}")
            return {'success': False, 'message': str(e)}

    def batch_update_polish(self, works: List[Dict]) -> Dict:
        """
        批量更新润色结果

        Args:
            works: 润色结果列表
                [
                    {
                        'platform': 0,
                        'workId': 'xxx',
                        'polishedText': '润色后文本',
                        'polishStatus': 1,
                        'polishEngine': 'deepseek-chat',
                        'qualityScore': 85
                    },
                    ...
                ]

        Returns:
            {
                'success': True/False,
                'updated': 10,
                'failed': 0
            }
        """
        url = f"{self.api_url}{self.api_prefix}/worker/batch-update-polish"

        payload = {'works': works}

        try:
            self.logger.info(f"批量更新润色结果: {len(works)}条")

            # 调试日志：打印第一条数据
            if works:
                self.logger.debug(f"第一条数据示例: {works[0]}")

            response = self.session.post(url, json=payload, timeout=self.timeout)
            response.raise_for_status()
            result = response.json()

            if result.get('success'):
                self.logger.info(
                    f"润色更新完成: 成功{result.get('updated', 0)}条, "
                    f"失败{result.get('failed', 0)}条"
                )
            else:
                self.logger.error(f"批量更新失败: {result.get('message', '未知错误')}")

            # 如果有失败，打印详细信息
            if result.get('failed', 0) > 0:
                self.logger.warning(f"部分更新失败，响应详情: {result}")

            return result

        except requests.exceptions.RequestException as e:
            self.logger.error(f"批量更新润色失败: {str(e)}")
            return {'success': False, 'message': str(e)}


if __name__ == '__main__':
    # 测试代码
    config = {
        'api_url': 'http://localhost:8001',
        'timeout': 30,
        'retry_times': 3,
    }

    client = APIClient(config)

    # 测试健康检查
    if client.health_check():
        print("后台API正常")
    else:
        print("后台API无法访问")
